from stark.service.v1 import StarkHandler, get_choice_text, StarkModelForm, StarkForm, SearchGroupOption
from django.urls import re_path
from django.shortcuts import redirect, render
from web import models
from django import forms
from django.core.exceptions import ValidationError
from stark.utils.md5 import rev_md5
from django.utils.safestring import mark_safe
from .base import PermissionHandler


# 用户表增删改查

class UserInfoModelFormAdd(StarkModelForm):
    """自定制编辑页面form字段显示顺序"""
    # 1. 添加页面，增加确认密码字段
    re_password = forms.CharField(label='确认密码')

    class Meta:
        model = models.UserInfo
        fields = ['name', 'password', 're_password', 'nickname', 'gender', 'phone', 'email', 'depart', 'roles']

    # 2. 判断两次密码不一致，输出错误
    def clean_re_password(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if re_password != password:
            raise ValidationError('两次密码输入不一致')
        return re_password

    # 3. 添加密码 以密文形式保存到数据库
    def clean(self):
        password = self.cleaned_data.get('password')
        self.cleaned_data['password'] = rev_md5(password)
        return self.cleaned_data


class UserInfoModelFormEdit(StarkModelForm):
    # 编辑页面 去除密码字段
    class Meta:
        model = models.UserInfo
        fields = ['name', 'nickname', 'gender', 'phone', 'email', 'depart', 'roles']


class ResetPwdForm(StarkForm):
    # 重置密码form表单
    password = forms.CharField(label='新密码')
    re_password = forms.CharField(label='确认密码')

    # 2. 判断两次密码不一致，输出错误
    def clean_re_password(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if re_password != password:
            raise ValidationError('两次密码输入不一致')
        return re_password

    # 3. 添加密码 以密文形式保存到数据库
    def clean(self):
        password = self.cleaned_data.get('password')
        self.cleaned_data['password'] = rev_md5(password)
        return self.cleaned_data


class UserInfoHandler(PermissionHandler,StarkHandler):

    # 为用户列表页面定制 重置密码字段
    def display_reset_password(self, obj=None, is_header=None):
        if is_header:
            """重置密码"""
            return '密码操作'
        url = self.reverse_reset_url(pk=obj.pk)
        return mark_safe('<a href="%s">重置密码</a>' % url)

    search_list = ['nickname__contains', 'name__contains']
    search_group = [SearchGroupOption('gender'),
                    SearchGroupOption('depart')
                    ]
    field_name_list = [
        'nickname',
        get_choice_text('性别', 'gender'),
        'phone', 'email', 'depart',
        display_reset_password,
    ]

    # 重置密码的url反向解析
    def reverse_reset_url(self, *args, **kwargs):
        return self.reverse_commons(self.get_reset_url_name, *args, **kwargs)

    def get_model_form_class(self,is_add=False, *args, **kwargs):
        if is_add:
            return UserInfoModelFormAdd
        return UserInfoModelFormEdit

    # 重置密码的视图函数
    def reset_view(self, request, pk):
        form = ResetPwdForm()
        if request.method == 'POST':
            form = ResetPwdForm(data=request.POST)  # 验证表单
            user_obj = models.UserInfo.objects.filter(id=pk).first()
            if form.is_valid():
                # 密码更新到数据库
                user_obj.password = form.cleaned_data['password']
                user_obj.save()
                return redirect(self.redirect_url())  # 跳转页面
            return render(request, 'stark/change.html', {'forms': form})  # 发送错误信息
        return render(request, 'stark/change.html', {'forms': form})

    # 重置密码的携带原搜索条件的url解析
    @property
    def get_reset_url_name(self):
        return self.get_urls_name('reset')

    # 增加新的重置密码url
    def extra_urls(self):
        patterns = [re_path('reset/(?P<pk>\d+)/', self.wrapper(self.reset_view), name=self.get_reset_url_name), ]

        return patterns
